// GNU (L)GPLv3+ here.

#include "MaxsiGameEngine.h"

#ifdef Maxsi_Support_OpenGL

#include <X11/X.h>
#include <X11/Xlib.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/glu.h>
#include "Main.h"

bool			ExitedGameLoop		=	false;
bool			ShouldMainLoop		=	true;
MaxsiHandle		ShouldRenderEvent	=	NULL;
//MaxsiHandle		ExitedGameLoopEvent	=	NULL;

MaxsiError MainLoop()
{
	ShouldMainLoop	=	true;

	CreateWorkerThreadPool();

	ShouldRenderEvent		=	ThreadSystem()->CreateEvent();
	//ExitedGameLoopEvent		=	ThreadSystem()->CreateEvent();

	CreateScene();

	OnNewFrame();

	// Wait for the first frame to arrive!
	ThreadSystem()->WaitForEvent(ShouldRenderEvent);
	ThreadSystem()->WaitedForEvent(ShouldRenderEvent);

	while ( ShouldMainLoop == true )
	{
		// Simply render all that we can in this thread, we have a thread pool
		// of thread that takes care of the rest. While what we render might be
		// lagging behind the actual game, if we dos ome extrapolation, I don't
		// think people would notice.
		
		UpdateRenderGameTime();
		CalculateRenderFPS();

		CreateSceneRenderJobs();				

		usleep(1000);
	}

	// Poll until the loop has successfully exited!
	while ( ExitedGameLoop == false ) {	usleep(10000); }
	
	// Wait for the logic game loop to exit gracefully.
	//ThreadSystem()->WaitForEvent(ExitedGameLoopEvent);
	//ThreadSystem()->WaitedForEvent(ExitedGameLoopEvent);

	//ThreadSystem()->DeleteEvent(ExitedGameLoopEvent);
	ThreadSystem()->DeleteEvent(ShouldRenderEvent);

	DeleteScene();

	DeleteWorkerThreadPool();

	return MAXSI_ERROR_SUCCESS;
}

#if 0
void DrawAQuad()
{
	glClearColor(1.0, 1.0, 1.0, 1.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-1., 1., -1., 1., 1., 20.);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(0., 0., 10., 0., 0., 0., 0., 1., 0.);

	glBegin(GL_QUADS);

		glColor3f(1., 0., 0.); glVertex3f(-.75, -.75, 0.);
		glColor3f(0., 1., 0.); glVertex3f( .75, -.75, 0.);
		glColor3f(0., 0., 1.); glVertex3f( .75,  .75, 0.);
		glColor3f(1., 1., 0.); glVertex3f(-.75,  .75, 0.);

	glEnd();
}
#endif

int main(int argc, char** argv)
{
	if ( CreateWindow() != MAXSI_ERROR_SUCCESS ) { return 1; }
	if ( Create3DContext() != MAXSI_ERROR_SUCCESS ) { return 1; }

	InitLogicGameTime();
	InitRenderGameTime();

	MainLoop();

	Delete3DContext();
	DeleteWindow();

	return 0;
}

#endif
